package com.zrrd.blog.oauth2;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zrrd.blog.util.base.Result;
import com.zrrd.blog.util.enums.ResultEnum;
import com.zrrd.blog.util.tools.RequestUtil;
import org.apache.commons.collections.MapUtils;
import org.apache.http.HttpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

//认证成功处理器 校验客户端信息 生成jwt对象 返回Result对象

@Component("CustomAuthenticationSuccessHandler")
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private static final String HEADER_TYPE = "Basic ";

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthorizationServerTokenServices authorizationServerTokenServices;

    private ObjectMapper objectMapper;

    @Override

    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication)
            throws IOException, ServletException {
        //获取请求头，因为token在请求头中
        String header = request.getHeader(HttpHeaders.AUTHORIZATION);
        Result result = null;
        try {
            if (header == null || !header.startsWith(HEADER_TYPE)) {
                throw new UnsupportedEncodingException("请求头中没有客户端信息");
            }
            //解析请求头中的客户端信息
            String[] tokens = RequestUtil.extractAndDecodeHeader(header);
            assert tokens.length == 2;
            String clientId = tokens[0];
            String clientSecret = tokens[1];
            //查询客户端信息，核对是否有效
            ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
            if (clientDetails == null) {
                throw new UnsupportedOperationException("clientID对应配置不存在");
            }
            //校验客户端密码是否有效
            if (!passwordEncoder.matches(clientSecret, clientDetails.getClientSecret())) {
                throw new UnsupportedOperationException("无效的clientSecret");
            }
            //组合请求对象，去获取令牌
            TokenRequest tokenRequest = new TokenRequest(MapUtils.EMPTY_MAP, clientId, clientDetails.getScope(), "custom");
            OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
            OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
            OAuth2AccessToken accessToken = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);

            result = Result.ok(accessToken);
        } catch (Exception e) {
            result = Result.build(ResultEnum.AUTH_FAIL.getCode(), e.getMessage());
        }

        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString(request));

    }
}
